﻿using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;

namespace HobSoft.SoccerBet2014.Domain.Common.Service
{
    using Domain.Core;
    using Domain.IRepositories;
    using Domain.Models;
    using Domain.Models.KeyHelper;
    using Domain.DataService;
    public class BetGameDataService : IBetGameDataService
    {
        private readonly IGameRepository gameRepository;
        private readonly IOddsRepository oddsRepository;
        private readonly IMarketRepository marketRepository;

        [Inject]
        public BetGameDataService(
                                              IGameRepository _gameRepository
                                            , IOddsRepository _oddsRepository
                                            , IMarketRepository _marketRepository)
        {
            gameRepository = _gameRepository;
            oddsRepository = _oddsRepository;
            marketRepository = _marketRepository;
        }


        public Game GetGame(byte bookerId, string gameId)
        {
            var uniKeyRepository = gameRepository as IUniKeyReadRepository<Game>;
            if (uniKeyRepository == null)
            {
                return gameRepository.Get(bookerId, gameId);
            }
            else
            {
                var key = KeyGenerateHelper.Create<Game>(bookerId, gameId);
                return gameRepository.Get(key);
            }
        }

        public Odds GetOdds(byte bookerId, string oddsId)
        {
            var uniKeyRepository = oddsRepository as IUniKeyReadRepository<Odds>;
            if (uniKeyRepository == null)
            {
                return oddsRepository.Get(bookerId, oddsId);
            }
            else
            {
                var key = KeyGenerateHelper.Create<Odds>(bookerId, oddsId);
                return oddsRepository.Get(key);
            }
        }

        public Market GetMarket(byte bookerId, string gameId, string host)
        {
            var uniKeyRepository = marketRepository as IUniKeyReadRepository<Market>;
            if (uniKeyRepository == null)
            {
                return marketRepository.Get(bookerId, gameId, host);
            }
            else
            {
                var key = KeyGenerateHelper.Create<Market>(bookerId, gameId, host);
                return marketRepository.Get(key);
            }
        }

        public IList<Game> GetGames(byte bookerId, IEnumerable<string> gameIds)
        {
            var uniKeyRepository = gameRepository as IUniKeyReadRepository<Game>;
            if (uniKeyRepository == null)
            {
                gameRepository.GetMany(g => g.BmID == bookerId && gameIds.Contains(g.GameID));
            }
            var keys = gameIds.Select(g => KeyGenerateHelper.Create<Game>(bookerId, g));
            return uniKeyRepository.GetMany(keys);
        }

        public IList<Market> GetMarket(byte bookerId, string host, IEnumerable<string> gameIds)
        {

            var uniKeyRepository = marketRepository as IUniKeyReadRepository<Market>;
            if (uniKeyRepository == null)
            {
                return marketRepository.GetMany(m => m.BmID == bookerId && m.Host == host && gameIds.Contains(m.GameID));
            }
            var keys = gameIds.Select(g => KeyGenerateHelper.Create<Market>(bookerId, g, host));
            return uniKeyRepository.GetMany(keys);
        }

        public void UpdateRelatedGame(IList<Game> games, IList<Market> marketRange, IList<Odds> oddsRange)
        {
            gameRepository.UpdateRelatedEntities(games, marketRange, oddsRange);
        }

        public void UpdateAllGame(IList<Game> games)
        {
            gameRepository.AddOrUpdate(games);
        }

        public void UpdateAllOdds(IList<Odds> oddsRange)
        {
            oddsRepository.AddOrUpdate(oddsRange);
        }

        public void UpdateAllMarket(IList<Market> marketRange)
        {
            marketRepository.AddOrUpdate(marketRange);
        }

        public void UpdatePreGameOdds(byte bookerId, string gameId)
        {
            gameRepository.BackupPreGame(bookerId, gameId);
        }

        public void DeleteGames(byte bookerId, IEnumerable<string> gameIds)
        {
            gameRepository.DeleteMany(g => g.BmID == bookerId && gameIds.Contains(g.GameID));
        }

        public void DisableOdds(byte bookerId, string host, IEnumerable<string> oddsIds)
        {
            oddsRepository.Disable(bookerId, host, oddsIds.ToArray());
        }

        public void DisableGames(byte bookerId, IEnumerable<string> gameIds)
        {
            gameRepository.Finish(bookerId, gameIds.ToArray());
        }

        public void DeleteExpiredGames(DateTime startBefore)
        {
            gameRepository.DeleteMany(g => (g.StartTime.HasValue && g.StartTime.Value < startBefore || !g.StartTime.HasValue));
        }

    }
}
